namespace SimpleWebServices.Models
{
    using System.Xml.XPath;
    using SimpleWebServices;
    using Xunit;

    public sealed class ContactFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<Contact>()
                .DerivesFrom<object>()
                .IsConcreteClass()
                .IsSealed()
                .HasDefaultConstructor()
                .XmlRoot("contact")
                .Result);
        }

        [Fact]
        public void deserialize()
        {
            Contact actual = (
                "<contact key='test'>" +
                    "<addresses>" +
                        "<address />" +
                    "</addresses>" +
                    "<emails>" +
                        "<email />" +
                    "</emails>" +
                    "<name />" +
                    "<telephones>" +
                        "<telephone />" +
                    "</telephones>" +
                "</contact>").Deserialize<Contact>();

            Assert.NotNull(actual);

            Assert.NotEmpty(actual.Addresses);
            Assert.NotEmpty(actual.Emails);
            Assert.Equal<string>("test", actual.Key);
            Assert.NotNull(actual.Name);
            Assert.NotEmpty(actual.Telephones);
        }

        [Fact]
        public void deserializeEmpty()
        {
            Contact actual = "<contact />".Deserialize<Contact>();

            Assert.NotNull(actual);

            Assert.Empty(actual.Addresses);
            Assert.Empty(actual.Emails);
            Assert.Null(actual.Key);
            Assert.Null(actual.Name);
            Assert.Empty(actual.Telephones);
        }

        [Fact]
        public void serialize()
        {
            Contact obj = new Contact
            {
                Addresses =
                {
                    new InternationalAddress()
                },
                Emails =
                {
                    new Email()
                },
                Key = "test",
                Name = new PersonalName(),
                Telephones =
                {
                    new Telephone()
                }
            };

            XPathNavigator navigator = obj.Serialize().CreateNavigator();

            Assert.True((bool)navigator.Evaluate("1=count(/contact[@key='test']/addresses/address)"));
            Assert.True((bool)navigator.Evaluate("1=count(/contact[@key='test']/emails/email)"));
            Assert.True((bool)navigator.Evaluate("1=count(/contact[@key='test']/name)"));
            Assert.True((bool)navigator.Evaluate("1=count(/contact[@key='test']/telephones/telephone)"));
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new Contact());
        }

        [Fact]
        public void prop_Addresses()
        {
            Assert.True(new PropertyExpectations(typeof(Contact).GetProperty("Addresses"))
                .XmlElement("addresses")
                .TypeIs<InternationalAddressCollection>()
                .DefaultValueIsNotNull()
                .Result);
        }

        [Fact]
        public void prop_Emails()
        {
            Assert.True(new PropertyExpectations(typeof(Contact).GetProperty("Emails"))
                .XmlElement("emails")
                .TypeIs<EmailCollection>()
                .DefaultValueIsNotNull()
                .Result);
        }

        [Fact]
        public void prop_Key()
        {
            Assert.True(new PropertyExpectations(typeof(Contact).GetProperty("Key"))
                .XmlAttribute("key")
                .IsAutoProperty<string>()
                .Result);
        }

        [Fact]
        public void prop_Name()
        {
            Assert.NotNull(new PropertyExpectations(typeof(Contact).GetProperty("Name"))
                .XmlElement("name")
                .IsAutoProperty<PersonalName>()
                .Result);
        }

        [Fact]
        public void prop_Telephones()
        {
            Assert.True(new PropertyExpectations(typeof(Contact).GetProperty("Telephones"))
                .XmlElement("telephones")
                .TypeIs<TelephoneCollection>()
                .DefaultValueIsNotNull()
                .Result);
        }
    }
}